package com.example.ff.jobs;

import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Messenger;
import android.os.PersistableBundle;
import androidx.annotation.RequiresApi;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.navigation.NavigationView;
import com.google.android.material.snackbar.Snackbar;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.RadioGroup;
import android.widget.Switch;
import android.widget.TextView;

import java.lang.ref.WeakReference;
import java.util.List;

public class MainActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener {

    private static  int mJobId ;
    private static final String TAG = "MainActivity";

    private MJobMessageHandler jobHandler;

    private void startMJob(){
        Intent intent = new Intent(this,MJobService.class);
        jobHandler = new MJobMessageHandler(this);
        Messenger messenger = new Messenger(jobHandler);
        intent.putExtra(MJobConstant.MESSENGER_INTENT_KEY,messenger);
        startService(intent);
    }
    private static class MJobMessageHandler extends Handler{
        private final WeakReference<MainActivity> weakReference;
        MJobMessageHandler(MainActivity mainActivity){
            super();
            weakReference = new WeakReference<>(mainActivity);
        }
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case MJobConstant.MESSENGER_START:  {
                    MainActivity activity = weakReference.get();
                    Bundle data = msg.getData();
                    activity.txtRet.setText(data.getString(MJobConstant.MESSENGER_START_KEY));
                }break;
                case MJobConstant.MESSENGER_INTENT: break;
            }
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public void onScheduleClick(View view){
        JobInfo.Builder builder = new JobInfo.Builder(++mJobId, new ComponentName(this, MJobService.class));

        if (switchPeriodic.isChecked()){
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                builder.setPeriodic(1000 * 60 * 15);//最少15m
            }
        }else {
            String delay = edtMinimumLatency.getText().toString();
            if (!TextUtils.isEmpty(delay)) {
                builder.setMinimumLatency(Long.valueOf(delay) );
            }
            String deadline = edtMaxLatency.getText().toString();
            if (!TextUtils.isEmpty(deadline)) {
                builder.setOverrideDeadline(Long.valueOf(deadline));
            }
        }
        int connectivity = rGroupConnectivity.getCheckedRadioButtonId();
        if (connectivity == R.id.rdo_all){
            builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED);
        }else if(connectivity == R.id.rdo_wifi){
            builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
        }else{
            builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED);
        }
        builder.setRequiresDeviceIdle(chkIdle.isChecked());
        builder.setRequiresCharging(chkCharging.isChecked());
        builder.setPersisted(chkPersisted.isChecked());//开机

        //data
        PersistableBundle extras = new PersistableBundle();
        String data = edtData.getText().toString();
        extras.putString("JobData", data);
        if (switchPeriodic.isChecked()){
            extras.putInt("Periodic",1);
            int period = Integer.valueOf(edtPeriodic.getText().toString());
            if (period < 15){
                Snackbar.make(view,"周期任务时间间隔不能小于15m",Snackbar.LENGTH_SHORT).show();
                return;
            }
            extras.putInt("period",period);
        }else{
            extras.putInt("Periodic",0);
        }

        builder.setExtras(extras);

        // Schedule job
        Log.d(TAG, "Scheduling job");
        JobScheduler js = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
        if(null == js) return;
        JobInfo job = builder.build();
        int ret = js.schedule(job);
        if (ret == JobScheduler.RESULT_SUCCESS){
            Snackbar.make(view,"任务 ( " + job.getId() + " ) 布置成功",Snackbar.LENGTH_SHORT).show();
        }else{
            Snackbar.make(view,"任务 ( " + job.getId() + " ) 布置失败",Snackbar.LENGTH_SHORT).show();
        }
    }

    public void onCancelClick(View view){
        JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
        if (jobScheduler == null) return;
        List<JobInfo> allPendingJobs = jobScheduler.getAllPendingJobs();
        if(allPendingJobs.size() > 0){
            JobInfo jobInfo = allPendingJobs.get(allPendingJobs.size() - 1);
            int id = jobInfo.getId();
            jobScheduler.cancel(id);
            Snackbar.make(view,"任务 ( " + id + " ) 已经撤销",Snackbar.LENGTH_SHORT).show();
        }else{
            Snackbar.make(view,"没有任务",Snackbar.LENGTH_SHORT).show();
        }
    }
    public void onAllClick(View view){
        JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
        if (null == jobScheduler) return;
        List<JobInfo> allPendingJobs = jobScheduler.getAllPendingJobs();
        if(allPendingJobs.size() > 0){
            txtRet.setText("");
            for (JobInfo job : allPendingJobs){
                txtRet.append("jobId = " + job.getId() + " : ");
                txtRet.append("\nnetwork type = " + job.getNetworkType() + " , charging = " + job.isRequireCharging()
                + " , idle = " + job.isRequireDeviceIdle());
                txtRet.append("\nisPeriodic = " + job.isPeriodic() + " , isPersisted = " + job.isPersisted());
                txtRet.append("\nIntervalMillis = " + job.getIntervalMillis());
                txtRet.append("\nMinLatencyMillis = " + job.getMinLatencyMillis());
                txtRet.append("\nMaxExecutionDelayMillis = " + job.getMaxExecutionDelayMillis());
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                    txtRet.append("\nMinLatencyMillis = " + job.getTriggerContentUris());
                }
                txtRet.append("\ndata = " + job.getExtras().get("JobData"));
                txtRet.append("\n\n");
            }
        }else{
            txtRet.setText("没有任务");
        }
    }
    public void onCancelAllClick(View view){
        JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
        if (null == jobScheduler) return;
        List<JobInfo> allPendingJobs = jobScheduler.getAllPendingJobs();
        if(allPendingJobs.size() > 0){
            jobScheduler.cancelAll();
            Snackbar.make(view,"所有任务已经撤销",Snackbar.LENGTH_SHORT).show();
        }else{
            Snackbar.make(view,"没有任务",Snackbar.LENGTH_SHORT).show();
        }
    }

    @Override
    protected void onStart() {
        super.onStart();
    }


    private RadioGroup rGroupConnectivity;
    private EditText edtMinimumLatency,edtMaxLatency,edtPeriodic,edtData;

    private CheckBox chkCharging,chkIdle,chkPersisted;
    private Switch switchPeriodic;

    private TextView txtRet;

    private void createView(){
        rGroupConnectivity = findViewById(R.id.radioGroup);
        edtMinimumLatency = findViewById(R.id.edt_minimumLatency);
        edtMaxLatency = findViewById(R.id.edt_max_latency);
        edtData = findViewById(R.id.edt_data);
        edtPeriodic = findViewById(R.id.edt_periodic);

        chkCharging = findViewById(R.id.chk_charging);
        chkIdle = findViewById(R.id.chk_idle);
        chkPersisted = findViewById(R.id.chk_persisted);
        switchPeriodic = findViewById(R.id.switchPeriodic);

        txtRet = findViewById(R.id.txt_ret);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.addDrawerListener(toggle);
        toggle.syncState();

        NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);

        createView();

        startMJob();
    }

    @Override
    public void onBackPressed() {
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @SuppressWarnings("StatementWithEmptyBody")
    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        // Handle navigation view item clicks here.
        int id = item.getItemId();

        if (id == R.id.nav_camera) {
            // Handle the camera action
        } else if (id == R.id.nav_gallery) {

        } else if (id == R.id.nav_slideshow) {

        } else if (id == R.id.nav_manage) {

        } else if (id == R.id.nav_share) {

        } else if (id == R.id.nav_send) {

        }

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }
}
